React.memo
で関数をラップすると、関数にprops
が渡ってくる前に「更新必要そうか?」が確認されるようになります。もちろん、「更新必要なさそう」と判断された場合は前回返されたコンポーネントの結果が使われます。
例。
const Foo = React.memo(props => {
return {props.text}
});
これは以下と同等です。
const Foo = React.memo(
props => {
return {props.text}
},
(prevProps, nextProps) => {
return prevProps.text === nextProps.text;
}
);
1つ目の引数に渡すのは単に Functional Component ですが、2つ目の引数には前回のprops
と今回のprops
を使って何らかの確認を行う関数を渡します。この関数がfalse
を返すと「更新必要そう」と判断されます。
また2つ目の関数は省略可能で、渡さなかった場合は浅い比較での比較(オブジェクトの第一階層同士のチェック)を行う関数になります。
この部分をできるだけデフォルトの浅い比較で済ますためにuseMemo
やuseCallback
などのフックが役立ちます。直前に生成したオブジェクト値などをプロパティに渡すと、参照同士の比較で常にfalse
になってしまいますが、メモ関数から返された値を使うことで場合によってtrue
となる値を取得することができます。つまり、メモ関数によってオブジェクトが同じかどうかはメモの結果により既に求められている為、この部分の比較を簡略化することができます。
CodeSandbox上に例を作りました。ボタンをクリックすると親階層の状態が更新される事により子コンポーネントも更新されようとしますが、浅い比較によりMemoFoo
ではコンポーネントが更新されない事が確認できます。